const express = require('express');
const cors = require('cors');
const fs = require('fs');
const https = require('https');
const http = require('http');

const app = express();

app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());

const Global = require('./Global');
const Config = require('./Config');
const options = {
  key: fs.readFileSync(Config.ssl_key),
  cert: fs.readFileSync(Config.ssl_val)
}

async function main() {
  // 数据库初始化
  await Global.init()
  // http服务
  if (Config.ssl) {
    https.createServer(options, app).listen(Config.port, () => {
      console.log("HTTPS server started at " + Config.port);
    })
  } else {
    http.createServer(app).listen(Config.port, () => {
      console.log("HTTP server started at " + Config.port);
    })
  }

  // 授权登录
  app.get('/login', (req, res) => {
    const url = `https://api.weixin.qq.com/sns/jscode2session?appid=${Config.wx_appid}&secret=${Config.wx_secret}&js_code=${req.query.code}&grant_type=authorization_code`
    https.get(url, lis => {
      lis.on('data', data => {
        const obj = JSON.parse(data)
        if (obj.errcode) {
          res.send({ status: false, msg: '失败: 请检查appid和secret是否正确' })
          return
        }
        res.send({ status: true, openid: obj.openid })
      }).on('error', err => {
        res.send({ status: false, msg: '失败: 请检查appid和secret是否正确' })
        return
      });
    })
  })

  // 读取json
  // eg: http://127.0.0.1:3000/json-get?name=demo
  app.get('/json-get', (req, res) => {
    fs.readFile(`json/${req.query.name}.json`, 'utf-8', (err, data) => {
      if (err) {
        res.send([])
        return
      }
      res.send(data)
    })
  })

  // 获取排行榜
  app.get('/rank-get', async (req, res) => {
    const data = { my: [], top: [] }
    if (!req.query.openid) {
      res.send(data)
      return
    }
    // 当前用户排行和前n的排名
    let n = 50
    let op = await Global.collection('Rank').aggregate([
      // 按score进行排序
      {
        $sort: {
          'score': -1
        }
      },
      // 将行转化为集合存储
      {
        "$group": {
          "_id": null,
          "tableA": {
            "$push": "$$ROOT"
          }
        }
      },
      // 拆分集合为行，同时带上数组下标
      {
        $unwind: {
          path: '$tableA',
          includeArrayIndex: 'arrayIndex'
        }
      },
      {
        $project: {
          '_id': '$tableA._id',
          'openid': '$tableA.openid',
          'nickname': '$tableA.nickname',
          'avatar': '$tableA.avatar',
          'gender': '$tableA.gender',
          'score': '$tableA.score',
          'createTime': '$tableA.createTime',
          'updateTime': '$tableA.updateTime',
          'rank': { $add: ['$arrayIndex', 1] }
        }
      },
      // 对同一数据进行两次不同操作
      {
        $facet: {
          'my': [
            {
              $match: {
                'openid': req.query.openid
              }
            }
          ],
          // 获取前n的排名
          'top': [{
            $limit: n
          }, {
            $skip: 0
          }
          ]
        }
      }
    ]).toArray();
    res.send(op[0]);
  });

  // 设置排行榜
  app.post('/rank-set', async (req, res) => {
    let op = await Global.collection('Rank').findOne({ openid: req.body.openid });
    if (!op) {
      // 不存在记录则添加
      await Global.collection('Rank').insertOne({
        ...req.body,
        createTime: new Date(),
        updateTime: new Date()
      });
    } else {
      // 存在记录则修改
      await Global.collection('Rank').updateOne({
        openid: req.body.openid
      }, {
        $set: {
          updateTime: new Date()
        },
        $inc: {
          score: req.body.score
        }
      });
    }
    res.send(req.body);
  });

}

main().catch(e => {
  console.log(e)
  process.exit(-1);
})
